---
title: 'Chakra Factory'
package: '@chakra-ui/system'
description: Using the chakra factory and elements
category: 'features'
---

Chakra factory serves as an **object of chakra enabled JSX elements**, and also
**a function that can be used to enable custom component** receive chakra's
style props.

```bash
import { chakra } from "@chakra-ui/react"
```

## Chakra JSX Elements

Create base html elements with theme-aware style props using `chakra.<element>`
notation. For example, if you want a plain html button with ability to pass
chakra styles, you can write `<chakra.button />`.

```jsx
<chakra.button
  px='3'
  py='2'
  bg='green.200'
  rounded='md'
  _hover={{ bg: 'green.300' }}
>
  Click me
</chakra.button>
```

This reduces the need to create custom component wrappers and name them. This
syntax is available for common html elements. See the reference for the full
[list of elements](https://github.com/chakra-ui/chakra-ui/blob/main/packages/system/src/system.utils.ts#L9)
supported.

```jsx live=false
<chakra.h1 fontSize='lg'> Heading </chakra.h1>
```

## Chakra factory function

This is a function that converts **non-chakra components** or **jsx element** to
chakra-enabled components so you can pass style props to them.

Consider a package called `react-input-autoresize`, let's use the chakra factory
function to make possible to pass style props.

The function will infer the prop types from the wrapped component and also add
chakra style props.

```jsx live=false
import { chakra } from '@chakra-ui/react'
import Textarea from 'react-input-autoresize'

const AutoResizeInput = chakra(Textarea)

function Example() {
  return <AutoResizeInput bg='red.200' fontSize='12px' />
}
```

> Considering that Chakra uses `emotion` under the hood, ensure the non-chakra
> component accepts `className` as props for this to work correctly

### Attaching styles

In some instances, you might need to attach specific styles to the component
wrapped in the chakra factory

```jsx live=false
const AutoResizeInput = chakra(AutoResizeInput, {
  baseStyle: {
    bg: 'papayawhip',
    color: 'red.500',
  },
})
```

You can also use the chakra factory on jsx elements as well.

```jsx live=false
const Card = chakra('div', {
  baseStyle: {
    shadow: 'lg',
    rounded: 'lg',
    bg: 'white',
  },
})
```

### Allowing custom props to be forwarded

By default, the `chakra` factory only filters chakra related style props from
getting to the DOM. For more fine-grained control of how and what prop should be
forwarded, pass the `shouldForwardProp` option.

Here's a simple example that allows all props (including chakra's style props)
to pass through except the `sample` prop.

```jsx live=false
const Div = chakra('div', {
  shouldForwardProp: (prop) => !['sample'].includes(prop),
})
```

Another example that combines the default `shouldForwardProp` from Chakra UI
with custom logic.

```jsx live=false
import { chakra, shouldForwardProp } from '@chakra-ui/react'

const Div = chakra('div', {
  shouldForwardProp: (prop) => {
    // don't forward Chakra's props
    const isChakraProp = !shouldForwardProp(prop)
    if (isChakraProp) return false

    // else, only forward `sample` prop
    return ['sample'].includes(prop)
  },
})
```

To filter non-HTML attributes, you can leverage
[@emotion/is-prop-valid](https://github.com/emotion-js/emotion/tree/master/packages/is-prop-valid)
package.

```jsx live=false
import isValidHTMLProp from '@emotion/is-prop-valid'
import { chakra, shouldForwardProp } from '@chakra-ui/react'

const Div = chakra('div', {
  shouldForwardProp: (prop) => {
    // don't forward Chakra's props
    const isChakraProp = !shouldForwardProp(prop)
    if (isChakraProp) return false

    // forward valid HTML props
    const isValidProp = isValidHTMLProp(prop)
    if (isValidProp) return true

    // else, only forward `sample` prop
    return ['sample'].includes(prop)
  },
})
```
